package com.mikepenz.actionitembadge.library;
/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import ohos.aafwk.ability.AbilitySlice;
import ohos.agp.components.Attr;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.StackLayout;
import ohos.agp.components.Text;
import ohos.agp.utils.Color;
import ohos.app.Context;

import com.mikepenz.actionitembadge.library.utils.BadgeDrawableBuilder;
import com.mikepenz.actionitembadge.library.utils.BadgeStyle;
import com.mikepenz.actionitembadge.library.utils.Logger;
import com.mikepenz.actionitembadge.library.utils.UIUtil;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.typeface.IIcon;

import com.mikepenz.iconics.view.IconicsImageView;
import com.zyh.library.ResourceTable;

import java.util.Optional;

/**
 * @since 2021-06-03
 */
public class ActionItemBadge {
    private static Component styleComponent;
    private static boolean isHideTextbg = false;
    private static boolean isCheck;

    private final static int LBW = -2000000;
    private static int resIcons = LBW;

    /***
     * BadgeStyle 枚舉
     ***/
    public enum BadgeStyles {
        GREY(new BadgeStyle(BadgeStyle.Style.DEFAULT, ResourceTable.Layout_menu_action_item_badge,
            ohos.agp.utils.Color.getIntColor("#e0e0e0"),
            ohos.agp.utils.Color.getIntColor("#c7c7c7"), ohos.agp.utils.Color.BLACK.getValue())),
        DARK_GREY(new BadgeStyle(BadgeStyle.Style.DEFAULT, ResourceTable.Layout_menu_action_item_badge,
            ohos.agp.utils.Color.getIntColor("#606060"), ohos.agp.utils.Color.getIntColor("#3e3e3e"),
            ohos.agp.utils.Color.WHITE.getValue())),
        RED(new BadgeStyle(BadgeStyle.Style.DEFAULT, ResourceTable.Layout_menu_action_item_badge,
            ohos.agp.utils.Color.getIntColor("#FF4444"), ohos.agp.utils.Color.getIntColor("#CC0000"),
            ohos.agp.utils.Color.WHITE.getValue())),
        BLUE(new BadgeStyle(BadgeStyle.Style.DEFAULT, ResourceTable.Layout_menu_action_item_badge,
            ohos.agp.utils.Color.getIntColor("#33B5E5"), ohos.agp.utils.Color.getIntColor("#0099CC"),
            ohos.agp.utils.Color.WHITE.getValue())),
        GREEN(new BadgeStyle(BadgeStyle.Style.DEFAULT, ResourceTable.Layout_menu_action_item_badge,
            ohos.agp.utils.Color.getIntColor("#99CC00"), ohos.agp.utils.Color.getIntColor("#669900"),
            ohos.agp.utils.Color.WHITE.getValue())),
        PURPLE(new BadgeStyle(BadgeStyle.Style.DEFAULT, ResourceTable.Layout_menu_action_item_badge,
            ohos.agp.utils.Color.getIntColor("#AA66CC"), ohos.agp.utils.Color.getIntColor("#9933CC"),
            ohos.agp.utils.Color.WHITE.getValue())),
        YELLOW(new BadgeStyle(BadgeStyle.Style.DEFAULT, ResourceTable.Layout_menu_action_item_badge,
            ohos.agp.utils.Color.getIntColor("#FFBB33"), ohos.agp.utils.Color.getIntColor("#FF8800"),
            ohos.agp.utils.Color.WHITE.getValue())),
        GREY_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, ResourceTable.Layout_menu_action_item_badge_large,
            ohos.agp.utils.Color.getIntColor("#e0e0e0"), ohos.agp.utils.Color.getIntColor("#c7c7c7"),
            ohos.agp.utils.Color.BLACK.getValue())),
        DARK_GREY_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, ResourceTable.Layout_menu_action_item_badge_large,
            ohos.agp.utils.Color.getIntColor("#606060"), ohos.agp.utils.Color.getIntColor("#3e3e3e"),
            ohos.agp.utils.Color.WHITE.getValue())),
        RED_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, ResourceTable.Layout_menu_action_item_badge_large,
            ohos.agp.utils.Color.getIntColor("#FF4444"), ohos.agp.utils.Color.getIntColor("#CC0000"),
            ohos.agp.utils.Color.WHITE.getValue())),
        BLUE_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, ResourceTable.Layout_menu_action_item_badge_large,
            ohos.agp.utils.Color.getIntColor("#33B5E5"), ohos.agp.utils.Color.getIntColor("#0099CC"),
            ohos.agp.utils.Color.WHITE.getValue())),
        GREEN_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, ResourceTable.Layout_menu_action_item_badge_large,
            ohos.agp.utils.Color.getIntColor("#99CC00"), ohos.agp.utils.Color.getIntColor("#669900"),
            ohos.agp.utils.Color.WHITE.getValue())),
        PURPLE_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, ResourceTable.Layout_menu_action_item_badge_large,
            ohos.agp.utils.Color.getIntColor("#AA66CC"), ohos.agp.utils.Color.getIntColor("#9933CC"),
            ohos.agp.utils.Color.WHITE.getValue())),
        YELLOW_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, ResourceTable.Layout_menu_action_item_badge_large,
            ohos.agp.utils.Color.getIntColor("#FFBB33"), ohos.agp.utils.Color.getIntColor("#FF8800"),
            ohos.agp.utils.Color.WHITE.getValue()));
        private BadgeStyle style;

        BadgeStyles(BadgeStyle style) {
            this.style = style;
        }

        public BadgeStyle getStyle() {
            return style;
        }
    }

    public static boolean isIsHideTextbg() {
        return isHideTextbg;
    }

    public static void setIsHideTextbg(boolean isHideTextbg) {
        ActionItemBadge.isHideTextbg = isHideTextbg;
    }

    /**
     * 获取是否支持点击
     *
     * @return isCheck
     **/
    public static boolean isIsCheck() {
        return isCheck;
    }

    /**
     * 设置是否支持点击
     *
     * @param isCheck
     ***/
    public static void setIsCheck(boolean isCheck) {
        ActionItemBadge.isCheck = isCheck;
    }

    /**
     * 用于更新系统的图库
     *
     * @param act
     * @param resLayout 需要更新徽标的布局
     * @param icon 系统图库
     * @param badgeCount 图标上的数据
     **/
    public static void update(final AbilitySlice act, Component resLayout, IIcon icon, int badgeCount) {
        styleComponent = resLayout;
        IconicsImageView image = (IconicsImageView) resLayout.findComponentById(ResourceTable.Id_menu_badge_icon);
        if (badgeCount == Integer.MIN_VALUE) {
            IconicsDrawable drawable = new IconicsDrawable(image, resLayout.getContext(), icon);
            drawable.setColor(ohos.agp.utils.Color.WHITE);
            update(act, resLayout, drawable, BadgeStyles.DARK_GREY.getStyle(), null);
        } else {
            IconicsDrawable drawable = new IconicsDrawable(image, resLayout.getContext(), icon);
            drawable.setColor(ohos.agp.utils.Color.WHITE);
            update(act, resLayout, drawable, BadgeStyles.DARK_GREY.getStyle(), String.valueOf(badgeCount));
        }
    }

    /**
     * 用于更新系统的图库
     *
     * @param act
     * @param resLayout 需要更新徽标的布局
     * @param icon 系统图库
     * @param badgeCount 图标上的数据文本
     **/
    public static void update(final AbilitySlice act, Component resLayout, IIcon icon, String badgeCount) {
        styleComponent = resLayout;
        IconicsImageView image = (IconicsImageView) resLayout.findComponentById(ResourceTable.Id_menu_badge_icon);
        IconicsDrawable drawable = new IconicsDrawable(image, resLayout.getContext(), icon);
        drawable.setColor(ohos.agp.utils.Color.WHITE);
        update(act, resLayout, drawable, BadgeStyles.DARK_GREY.getStyle(), badgeCount);
    }

    /**
     * 用于更新系统的图库
     *
     * @param act
     * @param resLayout 需要更新徽标的布局
     * @param icon 系统图库
     * @param style 需要更新的款式类型
     * @param badgeCount 图标上的数据
     **/
    public static void update(final AbilitySlice act, Component resLayout, IIcon icon, BadgeStyle style, int badgeCount) {
        styleComponent = resLayout;
        if (badgeCount == Integer.MIN_VALUE) {
            IconicsImageView image = (IconicsImageView) resLayout.findComponentById(ResourceTable.Id_menu_badge_icon);
            IconicsDrawable drawable = new IconicsDrawable(image, resLayout.getContext(), icon);
            Logger.debug("ActionsetColor " + icon);
            drawable.setColor(ohos.agp.utils.Color.WHITE);
            update(act, resLayout, drawable, style, null);
        } else {
            IconicsImageView image = (IconicsImageView) resLayout.findComponentById(ResourceTable.Id_menu_badge_icon);
            IconicsDrawable drawable = new IconicsDrawable(image, resLayout.getContext(), icon);
            drawable.setColor(ohos.agp.utils.Color.WHITE);
            Logger.debug("ActionsetColor " + icon + " , drawable " + (drawable == null)
                + ", component " + resLayout.findComponentById(ResourceTable.Id_menu_badge_icon));
            update(act, resLayout, drawable, style, String.valueOf(badgeCount));
        }
    }

    /**
     * 用于更新系统的图库
     *
     * @param act
     * @param resLayout 需要更新徽标的布局
     * @param resIcon 本地传过来的资源图片id
     * @param style 需要更新的款式类型
     * @param badgeCount 图标上的数据
     **/
    public static void update(final AbilitySlice act, Component resLayout, int resIcon, BadgeStyle style, String badgeCount) {
        styleComponent = resLayout;
        resIcons = resIcon;
        if (resIcon != Integer.MAX_VALUE) {
            IconicsImageView image = (IconicsImageView) resLayout.findComponentById(ResourceTable.Id_menu_badge_icon);
            image.setPixelMap(resIcon);
        }
        update(act, resLayout, null, style, badgeCount, null);
    }

    /**
     * 用于更新系统的图库
     *
     * @param act
     * @param resLayout 需要更新徽标的布局
     * @param icon 系统图库
     * @param style 需要更新的款式类型
     * @param badgeCount 图标上的数据文本
     **/
    public static void update(final AbilitySlice act, Component resLayout, IIcon icon, BadgeStyle style, String badgeCount) {
        styleComponent = resLayout;
        IconicsImageView image = (IconicsImageView) resLayout.findComponentById(ResourceTable.Id_menu_badge_icon);
        IconicsDrawable drawable = new IconicsDrawable(image, resLayout.getContext(), icon);
        drawable.setColor(ohos.agp.utils.Color.WHITE);
        update(act, resLayout, drawable, style, badgeCount);
    }

    /**
     * 用于更新系统的图库
     *
     * @param act
     * @param resLayout 需要更新徽标的布局
     * @param icon 系统图库
     * @param iconColor 设置icon的颜色
     * @param badgeCount 图标上的数据
     **/
    public static void update(final AbilitySlice act, Component resLayout, IIcon icon, int iconColor, int badgeCount) {
        styleComponent = resLayout;
        update(act, null, icon, iconColor, BadgeStyles.DARK_GREY.getStyle(), badgeCount);
    }

    /**
     * 用于更新系统的图库
     *
     * @param act
     * @param resLayout 需要更新徽标的布局
     * @param icon 系统图库
     * @param iconColor 设置icon的颜色
     * @param style 需要更新的款式类型
     * @param badgeCount 图标上的数据
     **/
    public static void update(final AbilitySlice act, Component resLayout, IIcon icon, int iconColor, BadgeStyles style, int badgeCount) {
        styleComponent = resLayout;
        update(act, resLayout, icon, iconColor, style.getStyle(), badgeCount);
    }

    /**
     * 用于更新系统的图库
     *
     * @param act
     * @param resLayout 需要更新徽标的布局
     * @param icon 系统图库
     * @param iconColor 设置icon的颜色
     * @param style 需要更新的款式类型
     * @param badgeCount 图标上的数据
     **/
    public static void update(final AbilitySlice act, Component resLayout, IIcon icon, int iconColor, BadgeStyle style, int badgeCount) {
        styleComponent = resLayout;
        if (badgeCount == Integer.MIN_VALUE) {
            IconicsDrawable drawable = new IconicsDrawable(resLayout.findComponentById(ResourceTable.Id_menu_badge_icon),
                resLayout.getContext(), icon);
            drawable.setColor(new Color(iconColor));
            update(act, resLayout, drawable, style, null);
        } else {
            IconicsDrawable drawable = new IconicsDrawable(resLayout.findComponentById(ResourceTable.Id_menu_badge_icon),
                resLayout.getContext(), icon);
            drawable.setColor(new Color(iconColor));
            update(act, resLayout, drawable, style, String.valueOf(badgeCount));
        }
    }

    /**
     * 用于更新系统的图库
     *
     * @param act 对应的abilityslice
     * @param resLayout 需要更新徽标的布局
     * @param con 上下文
     * @param iconColor 设置icon的颜色
     * @param style 需要更新的款式类型
     * @param badgeCount 图标上的数据
     **/
    public static void update(final AbilitySlice act, Component resLayout, Context con,
                              int iconColor, BadgeStyle style, String badgeCount) {
        styleComponent = resLayout;
        IconicsDrawable drawable = new IconicsDrawable(resLayout, con);
        drawable.setColor(new Color(iconColor));
        update(act, resLayout, drawable, style, badgeCount);
    }

    /**
     * 用于更新系统的图库
     *
     * @param act
     * @param resLayout 需要更新徽标的布局
     * @param icon IconsicsDrawable图的组件
     * @param style 需要更新的款式类型
     * @param badgeCount 图标上的数据
     **/
    public static void update(final AbilitySlice act, Component resLayout, IconicsDrawable icon, BadgeStyles style, int badgeCount) {
        styleComponent = resLayout;
        if (badgeCount == Integer.MIN_VALUE) {
            update(act, resLayout, icon, style.getStyle(), null);
        } else {
            update(act, resLayout, icon, style.getStyle(), String.valueOf(badgeCount));
        }
    }

    /**
     * 用于更新系统的图库
     *
     * @param act
     * @param resLayout 需要更新徽标的布局
     * @param icon IconsicsDrawable图的组件
     * @param style 需要更新的款式类型
     * @param badgeCount 图标上的数据文本
     **/
    public static void update(final AbilitySlice act, Component resLayout, IconicsDrawable icon, BadgeStyles style, String badgeCount) {
        styleComponent = resLayout;
        update(act, resLayout, icon, style.getStyle(), badgeCount);
    }

    /**
     * 用于更新系统的图库的数字
     *
     * @param resLayout 需要更新徽标的布局
     * @param badgeCount 图标上的数据
     **/
    public static void update(Component resLayout, int badgeCount) {
        styleComponent = resLayout;
        update(resLayout, null, badgeCount);
    }

    /**
     * 用于更新系统的图库的数据
     *
     * @param resLayout 需要更新徽标的布局
     * @param badgeCount 图标上的数据
     **/
    public static void update(Component resLayout, String badgeCount) {
        styleComponent = resLayout;
        update(resLayout, null, badgeCount);
    }

    /**
     * 用于更新系统的图库
     *
     * @param resLayout 需要更新徽标的布局
     * @param icon IconsicsDrawable图的组件
     * @param badgeCount 图标上的数据
     **/
    public static void update(Component resLayout, IconicsDrawable icon, int badgeCount) {
        styleComponent = resLayout;
        if (badgeCount == Integer.MIN_VALUE) {
            update(null, resLayout, icon, (BadgeStyle) null, null);
        } else {
            update(null, resLayout, icon, (BadgeStyle) null, String.valueOf(badgeCount));
        }
    }

    /**
     * 用于更新系统的图库
     *
     * @param resLayout 需要更新徽标的布局
     * @param icon IconsicsDrawable图的组件
     * @param badgeCount 图标上的数据文本
     **/
    public static void update(Component resLayout, IconicsDrawable icon, String badgeCount) {
        styleComponent = resLayout;
        update(null, resLayout, icon, (BadgeStyle) null, badgeCount);
    }

    /**
     * 用于更新系统的图库
     *
     * @param activity
     * @param resLayout 需要更新徽标的布局
     * @param icon IconsicsDrawable图的组件
     * @param style 需要更新的款式类型
     * @param badgeCount 图标上的数据
     **/
    public static void update(final AbilitySlice activity, Component resLayout, IconicsDrawable icon, BadgeStyle style, int badgeCount) {
        styleComponent = resLayout;
        update(activity, resLayout, icon, style, badgeCount, null);
    }

    /**
     * 用于更新系统的图库
     *
     * @param activity
     * @param resLayout 需要更新徽标的布局
     * @param icon IconsicsDrawable图的组件
     * @param style 需要更新的款式类型
     * @param badgeCount 图标上的数据
     * @param listener 监听器
     **/
    public static void update(final AbilitySlice activity, Component resLayout, IconicsDrawable icon, BadgeStyle style, int badgeCount, ActionItemBadgeListener listener) {
        styleComponent = resLayout;
        if (badgeCount == Integer.MIN_VALUE) {
            update(activity, resLayout, icon, style, null, listener);
        } else {
            update(activity, resLayout, icon, style, String.valueOf(badgeCount), listener);
        }
    }

    /**
     * update the given menu item with icon, badgeCount and style
     *
     * @param activity use to bind onOptionsItemSelected
     * @param resLayout 需要更新徽标的布局
     * @param icon IconsicsDrawable图的组件
     * @param style 需要更新的款式类型
     * @param badgeCount 图标上的数据
     */
    public static void update(final AbilitySlice activity, Component resLayout, IconicsDrawable icon, BadgeStyle style, String badgeCount) {
        styleComponent = resLayout;
        update(activity, resLayout, icon, style, badgeCount, null);
    }

    /**
     * update the given menu item with icon, badgeCount and style
     *
     * @param abilitySlice use to bind onOptionsItemSelected / and to display the toast
     * @param resLayout 布局layout
     * @param icon
     * @param style
     * @param badgeCount
     * @param listener
     */
    private static void update(final AbilitySlice abilitySlice, Component resLayout
        , IconicsDrawable icon, BadgeStyle style, String badgeCount, final ActionItemBadgeListener listener) {
        if (resLayout == null) return;
        styleComponent = resLayout;
        StackLayout badge;
        Text badgeView;
        IconicsImageView imageView;
        imageView = (IconicsImageView) styleComponent.findComponentById(ResourceTable.Id_menu_badge_icon);
        badgeView = (Text) styleComponent.findComponentById(ResourceTable.Id_menu_badge);
        //Display icon in ImageView
        if (imageView != null && icon != null) {
            imageView.setIcon(icon);
        }
        if (abilitySlice != null && badgeCount != null) {
            styleComponent.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    if (fastClick() && isCheck == true) {
                        boolean consumed = false;
                        if (listener != null) {
                            consumed = listener.onOptionsItemSelected(styleComponent);
                        }

                        if (listener == null && myListener != null) {
                            myListener.onOptionsItemSelected(component);
                        }
                        if (!consumed) {
                        }
                    }

                }
            });

            styleComponent.setLongClickedListener(new Component.LongClickedListener() {
                @Override
                public void onLongClicked(Component component) {
                    boolean consumed1 = false;
                    if (longClickListener != null && isCheck == true) {
                        longClickListener.onOptionsItemLongSelected(component);
                    }
                }
            });
        }

        //Apply style if it's set
        if (style != null) {

            AttrSet attrSet = new AttrSet() {
                @Override
                public Optional<String> getStyle() {
                    return Optional.empty();
                }

                @Override
                public int getLength() {
                    return 0;
                }

                @Override
                public Optional<Attr> getAttr(int i) {
                    return Optional.empty();
                }

                @Override
                public Optional<Attr> getAttr(String s) {
                    return Optional.empty();
                }
            };

            if (icon != null) {
                UIUtil.setBackground(badgeView, new BadgeDrawableBuilder().corners(style.getCorner()).color(style.getColor()).colorPressed(style.getColorPressed()).strokeColor(style.getStrokeColor()).stroke(style.getStroke()).build(attrSet, abilitySlice));
            }

            if (isIsHideTextbg() == false) {
                UIUtil.setBackground(badgeView, new BadgeDrawableBuilder().corners(style.getCorner()).color(style.getColor()).colorPressed(style.getColorPressed()).strokeColor(style.getStrokeColor()).stroke(style.getStroke()).build(attrSet, abilitySlice));
            }

            ohos.agp.utils.Color color = new ohos.agp.utils.Color(style.getTextColor());
            badgeView.setTextColor(color);
        }
        Logger.debug("setActionText " + badgeCount);
        //Manage min value
        if (badgeCount == null) {
            badgeView.setVisibility(Component.HIDE);
        } else {
            badgeView.setVisibility(Component.VISIBLE);
            badgeView.setText(badgeCount);
        }

        badgeView.setText(badgeCount);
    }

    private static boolean fastClick() {
        long lastClick = 0;
        if (System.currentTimeMillis() - lastClick <= 500) {
            return false;
        }
        lastClick = System.currentTimeMillis();
        return true;
    }

    /**
     * hide the given menu item
     *
     * @param component 需要影藏的布局
     */
    public static void hide(Component component) {
        if (component != null) {
            component.setVisibility(Component.INVISIBLE);
        }
    }

    private static ActionItemBadgeLongListener longClickListener;

    /**
     * 获取长按监听
     *
     * @return 长按监听
     **/
    public static ActionItemBadgeLongListener getLongClickListener() {
        return longClickListener;
    }

    /**
     * 设置长按监听
     *
     * @param longClickListener
     **/
    public static void setLongClickListener(ActionItemBadgeLongListener longClickListener) {
        ActionItemBadge.longClickListener = longClickListener;
    }

    public interface ActionItemBadgeLongListener {

        /**
         * 让组件获取长按事件
         *
         * @param component 监听长按的某个控件
         * @return boolean
         **/
        boolean onOptionsItemLongSelected(Component component);
    }

    private static ActionItemBadgeListener myListener;

    /**
     * 获取普通点击事件监听器
     *
     * @return 点击事件监听器
     */
    public static ActionItemBadgeListener getMyListener() {
        return myListener;
    }

    /**
     * 设置监听器
     *
     * @param myListener
     */
    public static void setMyListener(ActionItemBadgeListener myListener) {
        ActionItemBadge.myListener = myListener;
    }

    public interface ActionItemBadgeListener {
        /**
         * item被选中接口
         *
         * @param component 监听单击的某个控件
         * @return boolean
         **/
        boolean onOptionsItemSelected(Component component);
    }
}
